#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
MCP Calculator Server - Enhanced MCP Tools

增强的MCP工具集合
"""

import asyncio
import time
import json
from typing import Dict, Any, List, Optional, Union
from datetime import datetime, timedelta
from mcp.server.fastmcp import FastMCP

from .calculator_engine import CalculatorEngine
from .history_manager import HistoryManager, CalculationRecord
from .logging_utils import timing_decorator, EnhancedLogger
from .config import config_manager

class EnhancedMCPTools:
    """增强的MCP工具类"""
    
    def __init__(self, mcp_server: FastMCP, logger: EnhancedLogger):
        self.mcp = mcp_server
        self.logger = logger
        self.calculator = CalculatorEngine()
        self.history = HistoryManager(
            max_memory_records=config_manager.server_config.max_history_size
        )
        
        # 注册所有工具
        self._register_tools()
        self._register_resources()
    
    def _register_tools(self):
        """注册所有工具"""
        
        @self.mcp.tool()
        @timing_decorator("basic_add", self.logger)
        def add(a: float, b: float) -> str:
            """加法运算
            
            Args:
                a: 第一个数字
                b: 第二个数字
                
            Returns:
                加法运算结果
            """
            start_time = time.time()
            result_data = self.calculator.basic_operation(a, b, 'add')
            duration = time.time() - start_time
            
            # 记录历史
            record = CalculationRecord(
                expression=f"{a} + {b}",
                result=result_data['result'] if result_data['success'] else result_data['error'],
                operation_type='add',
                success=result_data['success'],
                error_message=result_data['error'],
                duration=duration
            )
            self.history.add_record(record)
            
            if result_data['success']:
                return result_data['expression']
            else:
                return f"错误: {result_data['error']}"
        
        @self.mcp.tool()
        @timing_decorator("basic_subtract", self.logger)
        def subtract(a: float, b: float) -> str:
            """减法运算
            
            Args:
                a: 被减数
                b: 减数
                
            Returns:
                减法运算结果
            """
            start_time = time.time()
            result_data = self.calculator.basic_operation(a, b, 'subtract')
            duration = time.time() - start_time
            
            record = CalculationRecord(
                expression=f"{a} - {b}",
                result=result_data['result'] if result_data['success'] else result_data['error'],
                operation_type='subtract',
                success=result_data['success'],
                error_message=result_data['error'],
                duration=duration
            )
            self.history.add_record(record)
            
            if result_data['success']:
                return result_data['expression']
            else:
                return f"错误: {result_data['error']}"
        
        @self.mcp.tool()
        @timing_decorator("basic_multiply", self.logger)
        def multiply(a: float, b: float) -> str:
            """乘法运算
            
            Args:
                a: 第一个数字
                b: 第二个数字
                
            Returns:
                乘法运算结果
            """
            start_time = time.time()
            result_data = self.calculator.basic_operation(a, b, 'multiply')
            duration = time.time() - start_time
            
            record = CalculationRecord(
                expression=f"{a} × {b}",
                result=result_data['result'] if result_data['success'] else result_data['error'],
                operation_type='multiply',
                success=result_data['success'],
                error_message=result_data['error'],
                duration=duration
            )
            self.history.add_record(record)
            
            if result_data['success']:
                return result_data['expression']
            else:
                return f"错误: {result_data['error']}"
        
        @self.mcp.tool()
        @timing_decorator("basic_divide", self.logger)
        def divide(a: float, b: float) -> str:
            """除法运算
            
            Args:
                a: 被除数
                b: 除数
                
            Returns:
                除法运算结果
            """
            start_time = time.time()
            result_data = self.calculator.basic_operation(a, b, 'divide')
            duration = time.time() - start_time
            
            record = CalculationRecord(
                expression=f"{a} ÷ {b}",
                result=result_data['result'] if result_data['success'] else result_data['error'],
                operation_type='divide',
                success=result_data['success'],
                error_message=result_data['error'],
                duration=duration
            )
            self.history.add_record(record)
            
            if result_data['success']:
                return result_data['expression']
            else:
                return f"错误: {result_data['error']}"
        
        @self.mcp.tool()
        @timing_decorator("power_operation", self.logger)
        def power(a: float, b: float) -> str:
            """幂运算
            
            Args:
                a: 底数
                b: 指数
                
            Returns:
                幂运算结果
            """
            start_time = time.time()
            result_data = self.calculator.basic_operation(a, b, 'power')
            duration = time.time() - start_time
            
            record = CalculationRecord(
                expression=f"{a} ^ {b}",
                result=result_data['result'] if result_data['success'] else result_data['error'],
                operation_type='power',
                success=result_data['success'],
                error_message=result_data['error'],
                duration=duration
            )
            self.history.add_record(record)
            
            if result_data['success']:
                return result_data['expression']
            else:
                return f"错误: {result_data['error']}"
        
        @self.mcp.tool()
        @timing_decorator("modulo_operation", self.logger)
        def modulo(a: float, b: float) -> str:
            """取模运算
            
            Args:
                a: 被除数
                b: 除数
                
            Returns:
                取模运算结果
            """
            start_time = time.time()
            result_data = self.calculator.basic_operation(a, b, 'modulo')
            duration = time.time() - start_time
            
            record = CalculationRecord(
                expression=f"{a} % {b}",
                result=result_data['result'] if result_data['success'] else result_data['error'],
                operation_type='modulo',
                success=result_data['success'],
                error_message=result_data['error'],
                duration=duration
            )
            self.history.add_record(record)
            
            if result_data['success']:
                return result_data['expression']
            else:
                return f"错误: {result_data['error']}"
        
        @self.mcp.tool()
        @timing_decorator("expression_calculate", self.logger)
        def calculate(expression: str) -> str:
            """计算复杂数学表达式
            
            Args:
                expression: 数学表达式（支持 +, -, *, /, ^, %, (), 数学函数和常数）
                
            Returns:
                计算结果
            """
            start_time = time.time()
            
            # 检查缓存
            cache_key = f"expr:{expression}"
            cached_result = self.history.get_cached_result(cache_key)
            if cached_result:
                self.logger.info(f"使用缓存结果: {expression}")
                return cached_result
            
            result_data = self.calculator.evaluate_expression(expression)
            duration = time.time() - start_time
            
            # 记录历史
            record = CalculationRecord(
                expression=expression,
                result=result_data['result'] if result_data['success'] else result_data['error'],
                operation_type='calculate',
                success=result_data['success'],
                error_message=result_data['error'],
                duration=duration,
                metadata={
                    'processed_expression': result_data.get('processed_expression'),
                    'from_cache': False
                }
            )
            self.history.add_record(record)
            
            if result_data['success']:
                response = f"表达式: {expression}\n结果: {result_data['result']}"
                # 缓存成功的结果
                self.history.cache_result(cache_key, response)
                return response
            else:
                return f"错误: {result_data['error']}"
        
        @self.mcp.tool()
        def get_calculation_history(limit: int = 10, operation_type: Optional[str] = None) -> str:
            """获取计算历史记录
            
            Args:
                limit: 返回记录数量限制（默认10）
                operation_type: 操作类型过滤（可选）
                
            Returns:
                历史记录的JSON字符串
            """
            try:
                records = self.history.get_records(
                    limit=min(limit, 100),  # 最多100条
                    operation_type=operation_type
                )
                
                history_data = {
                    'total_records': len(records),
                    'records': [record.to_dict() for record in records]
                }
                
                return json.dumps(history_data, indent=2, ensure_ascii=False, default=str)
            except Exception as e:
                return f"获取历史记录失败: {str(e)}"
        
        @self.mcp.tool()
        def search_history(query: str, limit: int = 20) -> str:
            """搜索计算历史
            
            Args:
                query: 搜索关键词
                limit: 返回记录数量限制
                
            Returns:
                搜索结果的JSON字符串
            """
            try:
                records = self.history.search_records(query, limit)
                
                search_results = {
                    'query': query,
                    'total_found': len(records),
                    'records': [record.to_dict() for record in records]
                }
                
                return json.dumps(search_results, indent=2, ensure_ascii=False, default=str)
            except Exception as e:
                return f"搜索历史记录失败: {str(e)}"
        
        @self.mcp.tool()
        def get_statistics(days: int = 7) -> str:
            """获取计算统计信息
            
            Args:
                days: 统计天数（默认7天）
                
            Returns:
                统计信息的JSON字符串
            """
            try:
                stats = self.history.get_statistics(days)
                return json.dumps(stats, indent=2, ensure_ascii=False, default=str)
            except Exception as e:
                return f"获取统计信息失败: {str(e)}"
        
        @self.mcp.tool()
        def get_function_help(function_name: Optional[str] = None) -> str:
            """获取数学函数帮助信息
            
            Args:
                function_name: 函数名称（可选，不提供则返回所有函数列表）
                
            Returns:
                函数帮助信息
            """
            return self.calculator.get_function_help(function_name)
        
        @self.mcp.tool()
        def clear_cache() -> str:
            """清空计算缓存
            
            Returns:
                操作结果
            """
            try:
                self.history.clear_cache()
                self.calculator.clear_cache()
                return "缓存已清空"
            except Exception as e:
                return f"清空缓存失败: {str(e)}"
        
        @self.mcp.tool()
        def get_cache_info() -> str:
            """获取缓存信息
            
            Returns:
                缓存信息的JSON字符串
            """
            try:
                cache_info = {
                    'calculator_cache': self.calculator.get_cache_info(),
                    'result_cache': self.history.result_cache.get_stats()
                }
                return json.dumps(cache_info, indent=2, ensure_ascii=False)
            except Exception as e:
                return f"获取缓存信息失败: {str(e)}"
        
        @self.mcp.tool()
        def get_server_status() -> str:
            """获取服务器状态信息
            
            Returns:
                服务器状态的JSON字符串
            """
            try:
                from .logging_utils import get_system_metrics
                
                status = {
                    'server_info': {
                        'name': config_manager.server_config.name,
                        'version': config_manager.server_config.version,
                        'uptime': time.time(),  # 简化的运行时间
                    },
                    'system_metrics': get_system_metrics(),
                    'cache_stats': {
                        'calculator_cache': self.calculator.get_cache_info(),
                        'result_cache': self.history.result_cache.get_stats()
                    },
                    'recent_activity': len(self.history.get_recent_records(10))
                }
                
                return json.dumps(status, indent=2, ensure_ascii=False, default=str)
            except Exception as e:
                return f"获取服务器状态失败: {str(e)}"
        
        @self.mcp.tool()
        def export_history(file_path: str, format: str = 'json', days: int = 30) -> str:
            """导出计算历史
            
            Args:
                file_path: 导出文件路径
                format: 导出格式（json或csv）
                days: 导出最近多少天的数据
                
            Returns:
                导出结果
            """
            try:
                start_time = datetime.now() - timedelta(days=days)
                self.history.export_history(
                    file_path=file_path,
                    format=format,
                    start_time=start_time
                )
                return f"历史记录已导出到: {file_path}"
            except Exception as e:
                return f"导出历史记录失败: {str(e)}"
    
    def _register_resources(self):
        """注册资源"""
        
        @self.mcp.resource("calculator://operation/{operation}")
        def get_operation_info(operation: str) -> str:
            """获取运算操作的说明信息
            
            Args:
                operation: 运算类型
                
            Returns:
                运算操作的详细说明
            """
            operations = {
                "add": "加法运算：计算两个数的和，例如 3 + 5 = 8",
                "subtract": "减法运算：计算两个数的差，例如 10 - 3 = 7",
                "multiply": "乘法运算：计算两个数的积，例如 4 × 6 = 24",
                "divide": "除法运算：计算两个数的商，例如 15 ÷ 3 = 5（注意除数不能为零）",
                "power": "幂运算：计算底数的指数次幂，例如 2 ^ 3 = 8",
                "modulo": "取模运算：计算除法的余数，例如 10 % 3 = 1",
                "calculate": "表达式计算：支持复杂数学表达式，包括数学函数和常数"
            }
            
            return operations.get(operation, f"未知的运算类型: {operation}")
        
        @self.mcp.resource("calculator://functions")
        def get_available_functions() -> str:
            """获取可用的数学函数列表
            
            Returns:
                可用函数的详细信息
            """
            return self.calculator.get_function_help()
        
        @self.mcp.resource("calculator://config")
        def get_server_config() -> str:
            """获取服务器配置信息
            
            Returns:
                服务器配置的JSON字符串
            """
            config_data = config_manager.get_all_config()
            return json.dumps(config_data, indent=2, ensure_ascii=False)
        
        @self.mcp.resource("calculator://metrics")
        def get_metrics() -> str:
            """获取服务器指标
            
            Returns:
                服务器指标的JSON字符串
            """
            try:
                metrics = self.logger.metrics.get_metrics_summary()
                return json.dumps(metrics, indent=2, ensure_ascii=False, default=str)
            except Exception as e:
                return f"获取指标失败: {str(e)}"